/***************************************************************
 *  Copyright (c) 2007 by GroupMe! Team (www.groupme.net)
 *  All rights reserved.
 *
 *  This file is part of the GroupMe! Project. Source code of 
 *  this project is closed and redistribution of this code is
 *  prohibited. 
 *  
 *  Contact: http://www.groupme.net
 *
 *  This copyright notice MUST APPEAR in all copies of the file!
 ***************************************************************/
package net.groupme.search.rss;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import net.groupme.controller.model.RssSearchResult;
import net.groupme.controller.model.SearchResult;
import net.groupme.model.MODEL_CONSTANTS;
import net.groupme.search.google.Google_Vocabulary;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.soap.search.GoogleSearch;
import com.google.soap.search.GoogleSearchFault;
import com.google.soap.search.GoogleSearchResult;
import com.google.soap.search.GoogleSearchResultElement;

import de.nava.informa.core.ChannelIF;
import de.nava.informa.core.ParseException;
import de.nava.informa.impl.basic.ChannelBuilder;
import de.nava.informa.impl.basic.Item;
import de.nava.informa.parsers.FeedParser;

/**
 * created on 06.07.2007
 * 
 * This class/interface...
 * 
 * @author Patrick Siehndel <a
 *         href="mailto:patrick.siehndel@gmx.de">patrick.siehndel@gmx.de</a>
 * @author last edited by: $Author: patrick $
 * 
 * @version $Revision: 1.7 $ $Date: 2008-12-01 13:02:49 $
 */
public class RssSearchEngine {

	
	/** Logger for this class and subclasses */
	protected final Log logger = LogFactory.getLog(getClass());
	/**
	 * Returns an Array of {@link SearchResult} instances that suit the given
	 * query which are from the Google Search API
	 * 
	 * @param queryKeyword
	 *            The Keyword which is searched for
	 * @param numberOfResults
	 *            The Number of Results which are returned
	 * @return
	 */
	public List<SearchResult> searchRss(String queryKeyword, int numberOfResults) {

		GoogleSearch googleSearch = new GoogleSearch();
		googleSearch.setKey(Google_Vocabulary.Google_API_KEY);
		googleSearch.setQueryString("filetype:rss" + " " + queryKeyword);
		googleSearch.setMaxResults(10);
		GoogleSearchResult googleResult = new GoogleSearchResult();
		List<SearchResult> resultList = new ArrayList<SearchResult>();
		int counter = 0;
		try {
			googleResult = googleSearch.doSearch();
			GoogleSearchResultElement[] liste = googleResult
					.getResultElements();
			while (counter < (liste.length)) {
				SearchResult result = new SearchResult();
				result.setDescription(getDescriptionOfChannel(liste[counter]
						.getURL()));
				result.setName(cleanString(liste[counter].getTitle()));
				result.setResultID("rssresult" + counter);
				result.setType(MODEL_CONSTANTS.RESOURCE_TYPE_RSS);
				result.setUrl(liste[counter].getURL());
				resultList.add(result);
				counter++;
			}
			return resultList;
		} catch (GoogleSearchFault e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * Returns an Array containing one {@link SearchResult} instance that suit the given
	 * url, all other attributes of the search Result will be set automatically by the feed analyser
	 * 
	 * @param urloffeed
	 *            The URL of the Feed
	 * @return
	 */
	public List<SearchResult> addRss(String urloffeed) {
		
//		checks if both ( titel and Channels are null, and returns a empty result list if so.
		if (getTitelOfChannel(urloffeed) == null && getDescriptionOfChannel(urloffeed) == null){
			return  new ArrayList<SearchResult>();
		}
		
		ChannelIF channel = null;
		
		try {
			channel = FeedParser.parse(new ChannelBuilder(), urloffeed);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		List<SearchResult> resultList = new ArrayList<SearchResult>();
		int counter = 0;
		RssSearchResult result = new RssSearchResult();
		result.setDescription(channel.getDescription());
		result.setName(channel.getTitle());
		result.setResultID("result" + counter);
		result.setType(MODEL_CONSTANTS.RESOURCE_TYPE_RSS);
		result.setUrl(urloffeed);
		result.setCopyright(channel.getCopyright());
		result.setDocs(channel.getDocs());
		result.setFormat(channel.getFormat().toString());
		result.setIdOfFeed(channel.getId());
		if (channel.getImage() != null){
		result.setImageURL(channel.getImage().getLocation());
		}
		result.setLanguage(channel.getLanguage());
		result.setLocation(channel.getLocation());
		result.setPublisher(channel.getPublisher());
		result.setRssGenerator(channel.getGenerator());
		result.setSite(channel.getSite());
		result.setPubDate(channel.getPubDate());
		result.setLastUpdated(channel.getLastUpdated());
		resultList.add(result);
		
		
		//checks if both ( titel and Channels are null, and returns a empty result list if so.
		if (getTitelOfChannel(urloffeed) == null && getDescriptionOfChannel(urloffeed) == null){
			return  new ArrayList<SearchResult>();
		}
		return resultList;
		
		
	}

	/** cleans the < b> and < /b> out of the string */
	private String cleanString(String stri) {
		String ret = "";
		ret = stri.replaceAll("<b>", "");
		stri = ret.replaceAll("</b>", "");
		return stri;
	}
	
	/**
	 * Returns an List containing all {@link Item} instance that are in the feed
	 * 
	 * @param rssURL
	 *            The URL of the Feed
	 * @return
	 */
	public List<Item> getLatestItems(String rssURL) {
		ChannelIF channel = null;
		
		try {
			channel = FeedParser.parse(new ChannelBuilder(), rssURL);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		Iterator iter = channel.getItems().iterator();
		List<Item> itemList = new ArrayList<Item>();
		while (iter.hasNext()) {

			itemList.add(((Item) iter.next()));
		}
		return itemList;
	}

	/**
	 * Returns an String containing the Description of the Feed 
	 * 
	 * @param rssURL
	 *            The URL of the Feed
	 * @return
	 */
	private String getDescriptionOfChannel(String rssURL) {
		ChannelIF channel = null;
		try {
			channel = FeedParser.parse(new ChannelBuilder(), rssURL);
		} catch (IOException e) {
			logger.error("IOException while trying to parse Feed");
			return null;
		} catch (ParseException e) {
			logger.error("ParseException while trying to parse Feed");
			return null;
		}
		return channel.getDescription();
		
	}
	
	/**
	 * Returns an String containing the Titel of the Feed 
	 * 
	 * @param rssURL
	 *            The URL of the Feed
	 * @return
	 */
	private String getTitelOfChannel(String rssURL) {
		ChannelIF channel = null;
		try {
			channel = FeedParser.parse(new ChannelBuilder(), rssURL);
		} catch (IOException e) {
			logger.error("IOException while trying to parse Feed");
			return null;
		} catch (ParseException e) {
			logger.error("ParseException while trying to parse Feed");
			return null;
		}
		return channel.getTitle();
	}

}
